package com.adam.masterSpringMVC4.controller;

import com.adam.masterSpringMVC4.config.PictureUploadProperties;
import com.adam.masterSpringMVC4.profile.UserProfileSession;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.util.WebUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;

@Controller
public class PictureUploadController {

    private Resource uploadPath;
    private Resource anonymousPicture;
    private final MessageSource messageSource;
    private UserProfileSession userProfileSession;

    @Autowired
    public PictureUploadController(PictureUploadProperties pictureUploadProperties, MessageSource messageSource, UserProfileSession userProfileSession) {
        this.uploadPath = pictureUploadProperties.getUploadPath();
        this.anonymousPicture = pictureUploadProperties.getAnonymousPicture();
        this.userProfileSession = userProfileSession;
        this.messageSource = messageSource;
    }

    @RequestMapping("/upload")
    public String uploadPage() {
        return "uploadPage";
    }

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String onUpload(MultipartFile file, RedirectAttributes redirectAttributes, Model model) throws IOException {
        if(file == null || file.isEmpty() || !isImage(file)) {
            redirectAttributes.addFlashAttribute("error", "Incorrect file.");
            return "redirect:/profile";
        }
        String filename = file.getOriginalFilename();
        File tempFile = File.createTempFile("pic", getFileExtension(filename), uploadPath.getFile());
        try (InputStream in = file.getInputStream();
             OutputStream out = new FileOutputStream(tempFile)) {
            IOUtils.copy(in, out);
        }
        userProfileSession.setPicturePath(new FileSystemResource(tempFile));
        return "redirect:/profile";
    }

    @RequestMapping("/uploadedPicture")
    public void getUploadedPicture(HttpServletResponse response) throws IOException {
        Resource picturePath = userProfileSession.getPicturePath();
        if(picturePath == null) {
            userProfileSession.setPicturePath(anonymousPicture);
            picturePath = anonymousPicture;
        }
        response.setContentType(URLConnection.guessContentTypeFromName(picturePath.getFilename()));
        IOUtils.copy(picturePath.getInputStream(), response.getOutputStream());
    }

    @RequestMapping("uploadError")
    public ModelAndView onUploadError(HttpServletRequest request, Locale locale) {
        ModelAndView modelAndView = new ModelAndView("uploadPage");
        modelAndView.addObject("error", messageSource.getMessage(MultipartException.class.getName(), null, locale));
        return modelAndView;
    }

    private String getFileExtension(String fileName) {
        return fileName.substring(fileName.lastIndexOf('.'));
    }

    private boolean isImage(MultipartFile file) {
        return file.getContentType().startsWith("image");
    }

}
